package internal

import (
	"GameServer/Common/utils"
	"fmt"

	"github.com/globalsign/mgo/bson"
	log "github.com/sirupsen/logrus"

	"GameServer/Common/data"
	"GameServer/Game/errors"
	"GameServer/Game/m"
	"GameServer/Game/sp"
)

// 工会聊天
func (um *UnionManager) UnionChat(mid string, u *m.User, msg string, ext string, broadcastFunc func(uid string, data interface{})) (err error) {
	v, ok := m.Cache.Get("unionMembers", u.UnionId)
	if !ok {
		err = errors.NewErrcode(data.Errcode.NoUnion, fmt.Sprintf("公会成员获取失败,id:%s", u.UnionId))
		return
	}
	mMembers := v.(*m.UnionMembers)
	members := mMembers.MemberList()
	uid := u.Uid.Hex()
	bData := &sp.ChatNoticeRequest{
		Mid:         mid,
		Uid:         uid,
		Name:        u.Name,
		Head:        u.Head,
		Channel:     1,
		Msg:         msg,
		Time:        utils.TNow().Unix(),
		Ext:         ext,
		AvatarFrame: u.AvatarFrame,
	}

	chatMsg := &m.ChatMsg{
		Mid:  mid,
		Uid:  uid,
		Msg:  msg,
		Time: utils.TNow().Unix(),
		Ext:  ext,
		Type: 0,
	}
	err = m.AddUnionChatMsg(mMembers.UnionId, chatMsg)
	if err != nil {
		log.WithFields(log.Fields{
			"method": "UnionChat",
			"data":   chatMsg,
		}).Error(err)
	}

	utils.AsyncFunc(func() {
		for _, item := range members {
			if item.Uid == uid {
				continue
			}
			broadcastFunc(item.Uid, bData)
		}
	})
	return
}

func (um *UnionManager) UnionChatAll(us *m.User, msg string, ext string, broadcastFunc func(uid string, data interface{})) (err error) {
	v, ok := m.Cache.Get("unionMembers", us.UnionId)
	if !ok {
		err = errors.NewErrcode(data.Errcode.NoUnion, fmt.Sprintf("公会成员获取失败,id:%s", us.UnionId))
		return
	}
	mMembers := v.(*m.UnionMembers)
	members := mMembers.MemberList()
	uid := us.Uid.Hex()
	mid := bson.NewObjectId().Hex()
	bData := &sp.ChatNoticeRequest{
		Mid:         mid,
		Uid:         uid,
		Name:        us.Name,
		Head:        us.Head,
		Channel:     1,
		Msg:         msg,
		Time:        utils.TNow().Unix(),
		Ext:         ext,
		AvatarFrame: us.AvatarFrame,
	}

	chatMsg := &m.ChatMsg{
		Mid:  mid,
		Uid:  uid,
		Msg:  msg,
		Time: utils.TNow().Unix(),
		Ext:  ext,
		Type: 2,
	}

	unionEnergy := us.GetUnionEnergy()
	if unionEnergy.ReqMsg != nil && unionEnergy.ReqMsg.Mid != "" {
		// 删除玩家旧的体力请求
		m.DeleteUnionChatMsg(mMembers.UnionId, uid, mid)
	}
	// 每6小时可以请求赠送一次
	us.ResetUnionEnergyReqTime()
	// 重置体力请求
	unionEnergy.Reset(chatMsg)

	err = m.AddUnionChatMsg(mMembers.UnionId, chatMsg) // 添加玩家新的体力请求
	if err != nil {
		log.WithFields(log.Fields{
			"method": "UnionChat",
			"data":   chatMsg,
		}).Error(err)
	}

	utils.AsyncFunc(func() {
		for _, item := range members {
			broadcastFunc(item.Uid, bData)
		}
	})
	return
}

func (um *UnionManager) UnionSendEnergyChat(tu *m.User, msg *m.ChatMsg, broadcastFunc func(uid string, data interface{})) (err error) {
	v, ok := m.Cache.Get("unionMembers", tu.UnionId)
	if !ok {
		err = errors.NewErrcode(data.Errcode.NoUnion, fmt.Sprintf("公会成员获取失败,id:%s", tu.UnionId))
		return
	}
	mMembers := v.(*m.UnionMembers)
	members := mMembers.MemberList()
	bData := &sp.ChatNoticeRequest{
		Mid:         msg.Mid,
		Uid:         msg.Uid,
		Name:        tu.Name,
		Head:        tu.Head,
		Channel:     1,
		Msg:         msg.Msg,
		Time:        msg.Time,
		Ext:         msg.Ext,
		AvatarFrame: tu.AvatarFrame,
	}

	err = m.UpdateUnionChatMsg(mMembers.UnionId, msg)
	if err != nil {
		log.WithFields(log.Fields{
			"method": "UnionSendEneygyChat",
			"data":   msg,
		}).Error(err)
	}
	m.DeleteUnionChatMsgFullEnergy(mMembers.UnionId, tu.Uid.Hex()) // 满体力消息删除

	utils.AsyncFunc(func() {
		for _, item := range members {
			broadcastFunc(item.Uid, bData)
		}
	})
	return
}

func (um *UnionManager) UnionSysNotice(unionId string, langId int64, args []string, broadcastFunc func(uid string, data interface{})) (err error) {
	v, ok := m.Cache.Get("unionMembers", unionId)
	if !ok {
		err = errors.NewErrcode(data.Errcode.NoUnion, fmt.Sprintf("公会成员获取失败,id:%s", unionId))
		return
	}
	mMembers := v.(*m.UnionMembers)
	members := mMembers.MemberList()
	chatExt := &m.ChatExt{Type: 1, LangId: langId, Args: args}

	bData := &sp.ChatNoticeRequest{
		Mid:     bson.NewObjectId().Hex(),
		Channel: 1,
		Msg:     "",
		Time:    utils.TNow().Unix(),
		Ext:     chatExt.String(),
	}

	utils.AsyncFunc(func() {
		for _, item := range members {
			broadcastFunc(item.Uid, bData)
		}
	})
	return
}

func (um *UnionManager) UnionChatList(id string, req *sp.UnionChatMsgListRequest) (rList []*m.ChatMsg, num int, err error) {
	list, err := m.NewUnionChatMsg(id).GetMsgList()
	if err != nil {
		return
	}
	if len(list) == 0 {
		return
	}
	if req.Order == 0 {
		for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 {
			list[i], list[j] = list[j], list[i]
		}
	}

	start := int(req.Page * req.PageNum)
	num = len(list)
	if start >= num {
		return
	}
	end := start + int(req.PageNum)

	if req.Mid == "" {
		if end >= num {
			rList = list[start:]
			return rList, num, nil
		}
		rList = list[start:end]
		return
	}

	index := -1

	for i, item := range list {
		if item.Mid == req.Mid {
			index = i
		}
	}

	if index == len(list)-1 {
		return rList, 0, nil
	}

	if index == -1 {
		if end >= num {
			rList = list[start:]
			return rList, num, nil
		}
		rList = list[start:end]
		return
	}

	list = list[index:]
	num = len(list)
	if start >= num {
		return
	}
	if end >= num {
		rList = list[start:]
		return rList, num, nil
	}
	rList = list[start:end]
	return
}

func (um *UnionManager) UnionChatListAll(id string) (r []*m.ChatMsg, num int64, err error) {
	r, err = m.NewUnionChatMsg(id).GetMsgList()
	num = int64(len(r))
	return
}
